package com.yigerende.service.impl;

import com.yigerende.dao.BoardRepository;
import com.yigerende.model.Blog;
import com.yigerende.model.Comment;
import com.yigerende.model.Liucomment;
import com.yigerende.service.BoardService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class BoardServiceImpl implements BoardService {

    @Autowired
    private BoardRepository boardRepository;

    //分页查询所有
    @Override
    public Page<Liucomment> listLiu(Pageable pageable) {
        Page<Liucomment> liu = boardRepository.findAll(pageable);

        /*取出一页的所有显示放到集合进行转换*/
        List<Liucomment> liuPageList = eachComment(liu.getContent());
        /*List转Page*/
        Long totalCount=liu.getTotalElements();//总条数
        List<Liucomment> liuList=new ArrayList<>();
        for (Liucomment liuComments: liuPageList) {
            Liucomment liuVO=new Liucomment();
            BeanUtils.copyProperties(liuComments,liuVO);
            liuList.add(liuVO);
        }
        return new PageImpl(liuList,pageable,totalCount);
    }


    //把用户输入的信息保存到数据库
    @Transactional//这个方法放到一个事物里面（值刷新部分区域放到事物里面）
    @Override
    public Liucomment saveComment(Liucomment liucomment) {
        //先要判断这个用户的评论有没有父级（到底是回复的还是直接评论的）
        //默认parentCommentId为-1没有父级
        Long parentCommentId = liucomment.getParentComment().getId();//取到这个值进行判断

        //不等于-1的话，就说明用户是点击了回复的评论
        if(parentCommentId != -1){
            //通过id找到父级的评论,然后又传递给comment评论模型里面，现在评论模型里面就有父级评论和子级评论
            liucomment.setParentComment((Liucomment) boardRepository.findById(parentCommentId).get());
        }else {//等于-1就为父级评论
            liucomment.setParentComment(null);//就把是否有父级设置为空传递给数据库
        }
        //给一个创建时间
        liucomment.setCreateTime(new Date());
        //然后又把liucomment评论模型放入数据库
        return  boardRepository.save(liucomment);
    }





/**
 *
 * 总归的顺序是：
 * 1.找到所有的评论
 * 2.通过双for循环，把每一个顶级评论的二级子类评论找到进行传递
 * 3.把每一个二级子类评论再传递回去
 * */

    /**
     * 循环每个顶级的评论节点（就是最上面那一个）
     * */
    private  List<Liucomment> eachComment(List<Liucomment> liuComments){
        List<Liucomment> commentsView = new ArrayList<>();
        for (Liucomment comment : liuComments){
            Liucomment c = new Liucomment();
            BeanUtils.copyProperties(comment,c);
            commentsView.add(c);
        }
        combineChildren(commentsView);
        return commentsView;
    }

    /**
     * root根节点，blog不为空的对象集合
     * */
    private void combineChildren(List<Liucomment> liuComments){
        for (Liucomment comment : liuComments){
            List<Liucomment> replys1 = comment.getReplyComments();
            for (Liucomment reply1 : replys1){
                /**
                 * 循环迭代，找出子代，存放在tempReplys中
                 * 把二级子类给循环找出，后面的所有子类评论
                 */
                recursively(reply1);
            }
            //修改顶级节点的reply集合为迭代处理后的集合
            comment.setReplyComments(tempReplys);//把所有的二级评论和后面的所有评论都放在comment里面子级(ReplyComments)评论了
            //清楚临时存放区
            tempReplys = new ArrayList<>();
        }
    }


    //存放迭代找出的所有子代的集合，临时存放
    /**
     * 二级评论下面所有的评论都放到这个集合里面
     * */
    private List<Liucomment> tempReplys = new ArrayList<>();

    /*
     * 二级子类评论后面所有的评论
     * 上面传递过来二级子类
     * */
    private void recursively(Liucomment liuComments){
        tempReplys.add(liuComments);
        if (liuComments.getReplyComments().size()>0){
            List<Liucomment> replys = liuComments.getReplyComments();
            for (Liucomment reply : replys){
                tempReplys.add(reply);
                if (reply.getReplyComments().size()>0){//再进行判断这个评论里面还有没有评论（有的话再重复调用这个方法）
                    recursively(reply);
                }
            }
        }

    }

}
